#include "Insa.h"


Insa::Insa(Task **taskTable,int tasksCount,int machines)
{
	this->taskTable = taskTable;
	this->tasksCount = tasksCount;
	this->machines = machines;
	this->sortedTask = new Task [(tasksCount+1)*(machines+1)]();
	this->machinesTable = new Task* [machines+1]();
	
	this->machinesTable[0] = new Task [tasksCount+1]();
	for(int i =1;i<=machines;i++)
	{
		this->machinesTable[i] = new Task [tasksCount+1]();
	}

	this->Cmax = 0;

}

void Insa::QuickSort(int x, int y)
{
	Task v=sortedTask[(x+y)/2];
	int i,j;
	i=x;
	j=y;
	do{
		while (sortedTask[i]>v) i++;
		while (sortedTask[j]<v) j--;
		if (i<=j){
			std::swap(sortedTask[i],sortedTask[j]);
			i++; j--;
		}
	} while (i<=j);

	if (j>x) QuickSort(x, j);
	if (i<y) QuickSort(i, y);
}

int Insa::CMax()
{
	return this->Cmax;

}

void Insa::RiQ(Task **table)
{
	for(int i=this->tasksCount;i>=0;i--)
	{
		table[i][this->machines].q = table[i][this->machines].t;

		for(int j=this->machines-1;j>=0;j--)
		{
			table[i][j].q = table[i][j].t + table[i][j+1].q;
		}
		table[i][1].r = table[i][1].t;
		for(int j=2;j<=this->machines;j++)
		{
			table[i][j].r = table[i][j].t + table[i][j-1].r;
		}
	}
}

void Insa::Make()
{
	int count = 1;
	for(int i=this->tasksCount;i>=0;i--)
	{
		taskTable[i][this->machines].q = taskTable[i][this->machines].t;

		for(int j=this->machines-1;j>=0;j--)
		{
			taskTable[i][j].q = taskTable[i][j].t + taskTable[i][j+1].q;
		}
		taskTable[i][1].r = taskTable[i][1].t;
		sortedTask[count] = taskTable[i][1];
		count++;
		for(int j=2;j<=this->machines;j++)
		{
			taskTable[i][j].r = taskTable[i][j].t + taskTable[i][j-1].r;
			sortedTask[count] = taskTable[i][j];
			count++;
		}
	}
	QuickSort(1, tasksCount*machines);
#ifdef _DEBUG
	std::cout<<"po quick sort:"<<std::endl;
	for(int i = 1;i<=tasksCount*machines;i++)
	{
		//		for(int j= 1; j<=machines;j++)
		//	{
		std::cout<<"id: "<<sortedTask[i].id<<" t: "<<sortedTask[i].t<<" ";
		//	}
		std::cout<<std::endl;
	}
#endif

	int m;
	int pos;
	int bestPos;
	int cMaxT;
	int tmp;
	int *mC = new int[machines+1]();
	for(int i=1;i<=count;i++)
	{
		m = this->sortedTask[i].m;
		mC[m]++;
		cMaxT = INT_MAX;
		tmp = 0;
		bestPos = 0;
		pos = mC[m];

		this->machinesTable[m][mC[m]] = this->sortedTask[i];

		for(int j =1;j<=mC[m];j++)
		{
			if(m==1)
			std::cout<<std::endl;
			if(pos-1!=0)
			{
				if(m==1)
					std::cout<<"warunek 1 "<<machinesTable[m][pos-1].id<<" "<<machinesTable[m][pos].id<<std::endl;
				tmp =  machinesTable[m][pos-1].r + machinesTable[m][pos].q;
			}
			else 
			{
				if(m==1)
					std::cout<<"warunek 2 "<<" "<<machinesTable[m][pos].id<<" "<<machinesTable[m][pos+1].id<<std::endl;
				tmp =machinesTable[m][pos+1].q +  machinesTable[m][pos].r ;
			}
			if(m==1)
			std::cout<<std::endl;
			if(tmp <= cMaxT)
			{

				cMaxT = tmp;
				bestPos = pos;
				if(m==1)
				{
					std::cout<<"size: "<<mC[m]<<" pos "<<bestPos<<" m:"<<m <<" id: "<<this->machinesTable[m][bestPos].id<<" tmp: "<<tmp<<std::endl;
				}
			}

		}
		if(m==1)
		{
			std::cout<<std::endl;
			std::cout<<"Best pos :"<<bestPos<<std::endl;
		}
		if(pos - 1 !=0 )
		{
			std::swap(machinesTable[m][pos],machinesTable[m][pos-1]);
			pos--;
		}

		//Aktualizacja r i q 
		//if(m==1)
			//std::cout<<"R1 id :"<<this->machinesTable[m][1].id<<std::endl;
		this->machinesTable[m][1].r = this->machinesTable[m][1].t;

		for(int j=2;j<=mC[m];j++)
		{
			//this->machinesTable[m][j].r = std::max(this->machinesTable[m][j].t + this->machinesTable[m][j-1].r,
				//							this->taskTable[m][taskTable]);
		}
		//for(int j=2;j<=)
#if 0
		for(int j=-1;j>=1;j--)
		{
			if(m==1)
				std::cout<<" j: "<<j;
			this->taskTable[m][j].q = this->taskTable[m][j].t + this->taskTable[m][j+1].q;
		}
#endif

	}
	std::cout<<std::endl;
	for(int i = 1;i<=tasksCount;i++)
	{

		for(int j= 1; j<=machines;j++)
		{
			std::cout<<"id: "<<machinesTable[i][j].id<<" ";
		}
		std::cout<<std::endl;
	}
	
	
#if 0
	int m;
	int bestPos;
	int cMaxT;
	int *cM = new int [machines+1]();
	int pos;
	int tmp;
	for(int i = 1;i<=this->taskCount*machines;i++)
	{
		m = this->tasks[i].m;
		cM[m]++;
		cMaxT = INT_MAX;
		pos = cM[m];
		tmp = 0;
		bestPos = 0;
		this->taskTable[m][cM[m]] = this->tasks[i];

		for(int j =1;j<=cM[m];j++)
		{
#if 0

			this->taskTable[m][cM[m]].q = this->taskTable[m][cM[m]].t;

			for(int j=cM[m]-1;j>=1;j--)
			{
				this->taskTable[m][j].q = this->taskTable[m][j].t + this->taskTable[m][j+1].q;
			}
			this->taskTable[m][1].r = this->taskTable[m][1].t;

			for(int j=2;j<=cM[m];j++)
			{
				this->taskTable[m][j].r = this->taskTable[m][j].t + this->taskTable[m][j-1].r;
			}
#endif
			if(pos-1!=0)
			{
				if(m==1)
				std::cout<<"warunek 1 "<<taskTable[m][pos-1].id<<" "<<taskTable[m][pos].id<<std::endl;
				tmp =  taskTable[m][pos-1].r + taskTable[m][pos].q;
			}
			else 
			{
				if(m==1)
					std::cout<<"warunek 2 "<<" "<<taskTable[m][pos].id<<" "<<taskTable[m][pos+1].id<<std::endl;
				tmp =taskTable[m][pos+1].q +  taskTable[m][pos].r ;
			}
			if(tmp <= cMaxT)
			{
				
				cMaxT = tmp;
				bestPos = pos;
				if(m==1)
				{
					std::cout<<"size: "<<cM[m]<<" pos "<<bestPos<<" m:"<<m <<" id: "<<this->tasks[i].id<<" tmp: "<<tmp<<std::endl;
				}

			}
			if(m==1)
			std::cout<<std::endl;
			for(int j=1;j<=cM[m];j++)
			{
				if(m==1)
				{
					std::cout<<" id: "<<taskTable[m][j].id<<" t: "<<taskTable[m][j].t<<" r: "<<taskTable[m][j].r<<" q "<<taskTable[m][j].q<<std::endl;
				}
				
			}
			if(m==1)
			std::cout<<std::endl;
			if(pos - 1 !=0 )
			{
				std::swap(taskTable[m][pos],taskTable[m][pos-1]);
				pos--;
			}
			else
			{
				break;
			}

		}
		if(m==1)
		std::cout<<std::endl<<"wybrano :"<<bestPos<<std::endl;
		for(int z = 1;z <bestPos;z++)
		{
			std::swap(taskTable[m][z],taskTable[m][z+1]);
		}
		if(m==1)
		std::cout<<" m: "<<m<<" cM: "<<cM[m]<<std::endl;
		
		this->taskTable[m][machines].q = this->taskTable[m][cM[m]].t;
	
		for(int j=machines-1;j>=1;j--)
		{
			if(m==1)
			std::cout<<" j: "<<j;
			this->taskTable[m][j].q = this->taskTable[m][j].t + this->taskTable[m][j+1].q;
		}
		if(m==1)
		std::cout<<"R1 id :"<<this->taskTable[m][1].id<<std::endl;
		this->taskTable[m][1].r = this->taskTable[m][1].t;

		for(int j=2;j<=machines;j++)
		{
			if(m==1)
			std::cout<<" j2: "<<j;
			this->taskTable[m][j].r = this->taskTable[m][j].t + this->taskTable[m][j-1].r;
		}
		if(m==1)
		std::cout<<std::endl;
	}
#ifdef _DEBUG
	std::cout<<" policzenie R i Q"<<std::endl;
	for(int i = 1;i<=taskCount;i++)
	{
		
		for(int j= 1; j<=machines;j++)
		{
			
			std::cout<<"m: "<<taskTable[i][j].m<<" r: "<<taskTable[i][j].r<<" q:"<<taskTable[i][j].q<<" ";
		}
		std::cout<<std::endl;
	}
	for(int i = 1;i<=taskCount;i++)
	{

		for(int j= 1; j<=machines;j++)
		{
			std::cout<<"id: "<<taskTable[i][j].id<<" ";
		}
		std::cout<<std::endl;
	}
#endif
#endif
}

Insa::~Insa()
{

}